#![allow(dead_code)]

use away_mq_core::{auth::*, message::*, router::*};
use std::{
    io::{Read, Write},
    net::TcpStream,
};
use tokio::spawn;

#[derive(Default)]
pub struct Client {
    router: Router,
    socket: Option<TcpStream>,
    auth: Auth,
    token: String,
}

impl Client {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn connect(
        &mut self,
        addr: &str,
        username: &str,
        password: &str,
    ) -> Result<(), std::io::Error> {
        self.auth = Auth {
            username: username.to_string(),
            password: password.to_string(),
        };

        let socket = TcpStream::connect(addr)?;
        let mut buf = [0; 1024 * 10];
        self.socket = Some(socket.try_clone().unwrap());

        // auth
        // reader
        let mut r = socket.try_clone()?;
        let mut router = self.router.clone();
        spawn(async move {
            loop {
                let len = r.read(&mut buf).unwrap();
                if len == 0 {
                    continue;
                }

                router.run(&PayloadMessage::deserialize(&buf[0..len]).unwrap());
            }
        });

        return Ok(());
    }

    pub fn publish(&mut self, payload: PayloadMessage) {
        let mut socket = self.socket.as_ref().unwrap();
        socket.write_all(payload.serialize().as_bytes()).unwrap();
    }

    pub fn subscribe(&mut self, method: &str, handle: &'static RouterHandle) {
        self.router.add_router(method, handle);
    }
}
